package ocp.context;

import java.util.*;
import ocp.context.adapter.*;
import java.io.*;

/**
 */
public class HistoricalContext extends Observable implements java.io.Serializable
{
	
       // private static SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        
        /** Name of the context */
	protected String name = "nameless";
        
        /** Unique id of this context */
        protected String id = "";
        
        /** The contexts of the historical context */
        protected Vector contexts = null;        
        

	public HistoricalContext(String name, String id) {
            this.name = name;
            this.id = id;
            this.contexts = new Vector();
            //this.dateTime = new Long(System.currentTimeMillis());
	}

        /**
         * Adds a context to the historical context.
         * @param c the context to add.
         */
        public void addContext(Context c) {
            contexts.addElement(c);
        }

	public String getName()                         { return name; }
        public String getId()                           { return id; }
        public void setName(String newName)             { name = newName; }
        public void setId(String newId)                 { id = newId; }
                
        /**
         * returns the list of contexts of this Complex Context
         */
        public Iterator getContexts() {
            return contexts.iterator();
        }
        
	/** returns a string representation of the context, in XML format. */
	//public String toString()	{ return this.toXML(); }

        /** returns true if the given object is equal to this context, false otherwise */
        // TODO!!!!
        public boolean equals(Object o) {
            if (o instanceof HistoricalContext)
                return (((HistoricalContext) o).getId().equals(id));
            else return false;
        }

        
        /** Unique id of this context */
        //protected Long time;
        //protected Long dateTime;
        /* 
        public String getTime() {
            String s = null;
            Calendar c = Calendar.getInstance();
            c.setTimeInMillis(dateTime.longValue());
            s = (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")).format(c.getTime());
            return s;
        }
        
        public void updateTime(){
            this.dateTime = new Long(System.currentTimeMillis());
        }

        // SOS
        public void updateDateTime(String s){
            //this.dateTime = dateTime;
            this.dateTime = new Long(System.currentTimeMillis());
        }
        
        public HistoricalContext(String name, String id, ComponentAddress source, ComponentAddress notifier) {
            this.name = name;
            this.id = id;
            this.sourceInformation = source;
            this.notifierInformation = notifier;
            this.contexts = new Vector();
            //this.dateTime = new Long(System.currentTimeMillis());
	}

        protected ComponentAddress sourceInformation; 
        protected ComponentAddress notifierInformation;        
        
        
        public ComponentAddress getSourceInformation()  { return sourceInformation; }
        
        public ComponentAddress getNotifierInformation(){ return notifierInformation; }
        
        public void setSourceInformation(ComponentAddress si) {
            sourceInformation = si;
            //this.updateTime();
        }
        
        public void setNotifierInformation(ComponentAddress ni) {
            notifierInformation = ni;
            //this.updateTime();
        }        
        */     
	/** inform all observers of the context that the context changed. */
	/*
        public void contextChanged() {
		setChanged();
		notifyObservers();
	}
        */
	/** inform all observers of the context that the context changed, 
	 * giving some information about the change. */
	/*
        public void contextChanged(Object arg) {
		setChanged();
		notifyObservers(arg);
	}
	*/          

	/** 
	 * Stores the contextual information as an XML file.
	 * @param xmlFile thename of the file to generate
	 * @return true if context could be successfuly saved, false otherwise.
	 */
	/*
        public boolean storeAsXML(String xmlFile){

		String xml = this.toXML();

		// sanity check of the xml string.
		if (xml == null) return false;
		if (!xml.startsWith("<?xml")) xml = "<?xml version=\"1.0\"?>\n" + xml;
		try
		{
			PrintWriter pw = new PrintWriter(new BufferedWriter(
					new FileWriter(xmlFile)));
			pw.println(xml);
			pw.close();
			return true;
		} catch (IOException ioe) { return false; }
	}
        */
        
        
        /**
         * This method returns a string containing a XML representation of the
         * complex context. This xml string is composed by a combination of
         * all the contextual information that the context has, interpreted
         * by the contextual merger.
         */
        /*
        public String toXML() {

            ContextualInformationList cil = merger.mergeContexts(contexts);
            String xml = "<" + this.getClass().getSimpleName() + " name=\"" + name + "\" id=\"" + id + "\" dateTime=\"" + getTime() +"\">\n";

            if (!contexts.isEmpty()) {
                xml += "\t<Contexts>\n";
                for (Enumeration e = contexts.elements(); e.hasMoreElements();) {
                    xml += "\t" + ((Context) e.nextElement()).toXML() + "\n";
                }
                xml += "\t</Contexts>\n";
            }
            xml += "</" + this.getClass().getSimpleName() + ">\n";
            return xml;

            return "TODO";
        }
         */
        /*
        public boolean loadFromXML(String xmlFile) {
            // TODO
            XMLContextReader xmlcr = new XMLComplexContextReader(xmlFile, this);
            if (!xmlcr.isRunning())
            {
            try
            {
            data = xmlcr.read();
            } catch (IncompatibleContextualObjectException icoe) {
            return false;
            }
            }
            return true;
        }

        public synchronized String extractHierarchyAsString() {
            String hierarchy = "" + this.name + "->";
            for (Enumeration e = contexts.elements(); e.hasMoreElements();) {
                hierarchy += ((Context) e.nextElement()).extractHierarchyAsString();
            }
            return hierarchy;
        }        

        public ContextualInformationList getContextualInformation() throws ContextualInformationAbsentException {
            if (contexts == null) {
                throw new ContextualInformationAbsentException("Empty contexts for this complex context.");
            }
            if (merger == null) {
                throw new ContextualInformationAbsentException("Contexts can not be proccessed. Bad context intelligence.");
            }
            return merger.mergeContexts(contexts);
        }  
        */
         /** The context merger that combines the subcontexts of this context */
        //public ContextMerger merger = null;

        /** updates the contextual information, asking its adapter(s) */
        //public abstract void updateContextualInformation() 
        //	throws ContextualInformationAbsentException;

        /** returns the contextual information associated to this context */
        //public abstract ContextualInformationList getContextualInformation()
        //	throws ContextualInformationAbsentException;
    

}


